using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Xml;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;
using PS.WebParts.Rollup;
using PS.WebParts.Rollup.Core;

namespace PS.WebParts
{
    public interface IJoinable
    {
        FieldInfoCollection GetFields();

        [DefaultValue("<Where></Where>"), WebPartStorage(Storage.Personal), Description("CAML Query"), Bindable(true), Browsable(true), Category("RollUp Query"), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), PersistenceMode(PersistenceMode.InnerProperty)]
//[Browsable(true), Resources("QueryLiteral", "RollUp Query", "CAML Query"), PersistenceMode(PersistenceMode.InnerProperty), Personalizable(true)]
            string Query { get; set; }
    }

    [ParseChildren(ChildrenAsProperties = true),  PersistChildren(false)]
    [DefaultProperty("Query")]
    [Designer("PS.WebParts.Rollup.Designers.RollupDataSourceDesigner, PS.WebParts.Rollup.Designers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4f4a26fd125a021e")]
    public class RollUpDataSource : ATabularDataSource, IJoinable
    {
        [FriendlyName("From Top Level"), Description(""), Browsable(true), Category("RollUp"), DefaultValue(""), WebPartStorage(Storage.Personal)]
        public string TopLevelSite
        {
            get
            {
                return DSView.TopLevelSite;
            }
            set
            {
                DSView.TopLevelSite = value;
            }
        }


        protected ARollupDataSourceView DSView
        {
            get
            {
                return (ARollupDataSourceView)base.GetView();
            }
        }

        
        internal static bool IsFPDesignMode
        {
            get
            {
                HttpContext context = HttpContext.Current;
                return context == null || context.Request == null || context.Request.UserAgent.IndexOf("FrontPage") >= 0;
            }
        }


        override protected ATabularDataSourceView CreateViewInstance()
        {
            return new RollUpDataSourceView(base.Context, this, string.Empty);
        }

      
        public void SetParameters(Dictionary<string, object>  paras)
        {
            DSView.Parameters = paras;
        }
        
        ///<summary>
        ///Gets the named data source view associated with the data source control.
        ///</summary>
        ///
        ///<returns>
        ///Returns the named <see cref="T:System.Web.UI.DataSourceView"></see> associated with the <see cref="T:System.Web.UI.DataSourceControl"></see>.
        ///</returns>
        ///
        ///<param name="viewName">The name of the <see cref="T:System.Web.UI.DataSourceView"></see> to retrieve. In data source controls that support only one view, such as <see cref="T:System.Web.UI.WebControls.SqlDataSource"></see>, this parameter is ignored. </param>
        protected override DataSourceView GetView(string viewName)
        {
            return DSView;
        }

        [Description("This web, this web and its children, or entire site collection"), Category("RollUp"), WebPartStorage(Storage.Personal), DefaultValue(false), Browsable(true), FriendlyName("Lists in all SubSites")]
        public RollUpQueryWebScope Scope
        {
            get
            {
                return DSView.Scope;
            }
            set
            {
                DSView.Scope = value;
            }
        }

        [Browsable(true), WebPartStorage(Storage.Personal), Category("RollUp"), DefaultValue(""), FriendlyName("Lists"), Description("Lists to rollup format /site/subsite:List,/site/subsite/List")]
        public string Lists
        {
            get
            {
                return DSView.GetLists();
            }
            set
            {
                DSView.SetLists(value);
            }
        }

        internal void SetListFieldNames(string csvListFieldNames)
        {
            DSView.SetListFieldNames(csvListFieldNames);
        }

        [Obsolete, Browsable(false), Bindable(false)]
        public string ListFields
        {
            set
            {
                DSView.SetListFieldNames(value);
            }
        }


        [Category("RollUp"), FriendlyName("Include List data"), Browsable(true), Description("Include the list data underscore fields"), DefaultValue(false), WebPartStorage(Storage.Personal)]
        public bool IncludeListData
        {
            get
            {
                return DSView.IncludeListData;
            }
            set
            {
                DSView.IncludeListData = value;
            }
        }

        [Obsolete, Category(""), FriendlyName("Obsolete"), Browsable(false), Description("Use [QS:<queryStringKey>]"), DefaultValue(false), WebPartStorage(Storage.Personal)]
        public bool EnableQueryStringFilter
        {
            get
            {
                return false;
            }
            set
            { }
        }
        
        [DefaultValue(false), Category("RollUp"), WebPartStorage(Storage.Personal), FriendlyName("Dates in ISO8601"), Description("Dates in ISO8601"), Browsable(true)]
        public bool DatesInISO8601
        {
            get
            {
                return DSView.DatesInISO8601;
            }
            set
            {
                DSView.DatesInISO8601 = value;
            }
        }

        
        [Browsable(true), Description("Fix Lookups"), Category("RollUp"), DefaultValue(false), WebPartStorage(Storage.Personal), FriendlyName("Fix Lookups")]
        public bool FixLookups
        {
            get
            {
                return DSView.FixLookups;
            }
            set
            {
                DSView.FixLookups = value;
            }
        }

        
        //[Description(""), FriendlyName("Page Query String (ID)"), Browsable(false), Category("RollUp"), DefaultValue(""), WebPartStorage(Storage.Personal)]
        //public string PageQueryString
        //{
        //    get
        //    {
        //        return DSView.PageQueryString;
        //    }
        //    set
        //    {
        //        DSView.PageQueryString = value;
        //    }
        //}

        public FieldInfoCollection GetFields()
        {
            return DSView.Fields;
        }

        private string strOrigFields;
        [DefaultValue(""), WebPartStorage(Storage.Personal), Description("List Fields"), Bindable(true), Browsable(true), Category("RollUp"), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), PersistenceMode(PersistenceMode.InnerProperty)]
        public string Fields
        {
            get
            {
                FieldInfoCollection fields = DSView.Fields;

                if (fields.Count == 0 && !string.IsNullOrEmpty(strOrigFields))
                    return strOrigFields;

                StringBuilder sb = new StringBuilder(fields.Count * 20);

                foreach (FieldInfo info in fields)
                {
                    sb.AppendFormat("\n<FieldRef Name=\"{0}\" ", info.InternalName);
                    if (!string.IsNullOrEmpty(info.Alias))
                    {
                        sb.AppendFormat("Alias=\"{0}\" ", info.Alias);
                    }

                    if (!string.IsNullOrEmpty(info.Match))
                    {
                        sb.AppendFormat("Match=\"{0}\" ", info.Match);
                    }

                    if ( info.Type != SPFieldType.Invalid )
                    {
                        sb.AppendFormat("Type=\"{0}\" ", info.Type);
                    }

                    sb.Append("/>");
                }

                return sb.ToString();
            }
            set
            {
                strOrigFields = null;
                XmlDocument doc = new XmlDocument();
                try
                {
                    doc.LoadXml("<foo>"+ value + "</foo>");
                    FieldInfoCollection fields = DSView.Fields;
                    fields.Clear();
                    foreach (XmlNode node in doc.DocumentElement.ChildNodes)
                    {
                        if (node.LocalName != "FieldRef") continue;
                        XmlElement el = (XmlElement)node;
                       
                        string name = el.GetAttribute("Name");
                        if (string.IsNullOrEmpty(name))
                            continue;
                        FieldInfo info = new FieldInfo(name, el.GetAttribute("Alias"));
                        info.Match = el.GetAttribute("Match");
                        string strType = el.GetAttribute("Type");
                        if (!string.IsNullOrEmpty(strType))
                        {
                            try
                            {
                                info.Type = (SPFieldType)Enum.Parse(typeof (SPFieldType), strType, true);
                                
                            }catch(FormatException)
                            {
                            }
                        } else
                        {
                            info.Type = SPFieldType.Invalid;
                        }
                        fields.Add( info);
                    }
                }catch(XmlException)
                {
                    strOrigFields = value;
                }
            }
        }


        [DefaultValue("<Where></Where>"), WebPartStorage(Storage.Personal), Description("CAML Query"), Bindable(true), Browsable(true), Category("RollUp Query"), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), PersistenceMode(PersistenceMode.InnerProperty)]
        //[Browsable(true), Resources("QueryLiteral", "RollUp Query", "CAML Query"), PersistenceMode(PersistenceMode.InnerProperty), Personalizable(true)]
        public string Query
        {
            get
            {
                return DSView.Query;
            }
            set
            {
                DSView.Query = value;
            }
        }

        [DefaultValue(false), Description("Query Moderator"), Browsable(true), Category("RollUp Query"), WebPartStorage(Storage.Personal), FriendlyName("Query Moderator")]
        public bool QueryModerator
        {
            get
            {
                return DSView.QueryModerator;
            }
            set
            {
                DSView.QueryModerator = value;
            }
        }

        [WebPartStorage(Storage.Personal), Browsable(true), DefaultValue(false), Category("RollUp Query"), FriendlyName("Query Recursive"), Description("Query Recursive")]
        public bool QueryRecursive
        {
            get
            {
                return DSView.QueryRecursive;
            }
            set
            {
                DSView.QueryRecursive = value;
            }
        }

        [FriendlyName("CAML Query RowLimit"), Category("RollUp Query"), DefaultValue(""), WebPartStorage(Storage.Personal), Browsable(true), Description("CAML Query RowLimit")]
        public string QueryRowLimit
        {
            get
            {
                return DSView.GetQueryRowLimit();
            }
            set
            {
                DSView.SetQueryRowLimit(value);
            }
        }

        internal DataTable GetRollUpData(SPWeb web)
        {
            return DSView.GetRollUpData(web);
        }
        
        public DataTable GetRollUpData(string site)
        {
            return DSView.GetRollUpData(site);
        }

        [Description("Rollup the content of lists list,list in all subsites"), Category("RollUp"), DefaultValue(false), Browsable(false), FriendlyName("Lists in all SubSites")]
        public bool VisitSubSites
        {
            set
            {
                DSView.Scope = value ? RollUpQueryWebScope.Recursive : RollUpQueryWebScope.Web;
            }
        }
    }
}
